home *** CD-ROM | disk | FTP | other *** search
/ PC Media 7 / PC MEDIA CD07.iso / share / prog / cm / cmtordar.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-06  |  7.1 KB  |  317 lines

  1. // CmTOrdAr.cc
  2. // -----------------------------------------------------------------
  3. // Compendium - C++ Container Class Library
  4. // Copyright (C) 1992-1994, Glenn M. Poorman, All rights reserved
  5. // -----------------------------------------------------------------
  6. // Ordered array template implementation.
  7. // -----------------------------------------------------------------
  8.  
  9.  
  10. // "CmTOrderedArray" is the default array constructor.
  11. //
  12. template <class T>
  13. CmTOrderedArray<T>::CmTOrderedArray(unsigned sz, unsigned dt)
  14. {
  15.   _delta   = dt;
  16.   _total   = 0;
  17.   _entries = (sz > 0) ? new T[sz] : NULL;
  18.   _size    = (_entries != NULL) ? sz : 0;
  19. }
  20.  
  21.  
  22. // "CmTOrderedArray" is the array copy constructor.
  23. //
  24. template <class T>
  25. CmTOrderedArray<T>::CmTOrderedArray(const CmTOrderedArray<T>& A)
  26.                   : CmTContainer<T>(A)
  27. {
  28.   _total   = 0;
  29.   _entries = NULL;
  30.   copy(A);
  31. }
  32.  
  33.  
  34. // "=" assignment operator copies the specified array into this array.
  35. //
  36. template <class T>
  37. CmTOrderedArray<T>& CmTOrderedArray<T>::operator=(const CmTOrderedArray<T>& A)
  38. {
  39.   if (&A != this) copy(A);
  40.   return *this;
  41. }
  42.  
  43.  
  44. // "delta" sets a new delta value for automatic growing.
  45. //
  46. template <class T> void CmTOrderedArray<T>::delta(unsigned dt)
  47. {
  48.   _delta = dt;
  49. }
  50.  
  51.  
  52. // "delta" returns the current delta value.
  53. //
  54. template <class T> unsigned CmTOrderedArray<T>::delta() const
  55. {
  56.   return _delta;
  57. }
  58.  
  59.  
  60. // "total" returns the number of items in the array.
  61. //
  62. template <class T> int CmTOrderedArray<T>::total() const
  63. {
  64.   return _total;
  65. }
  66.  
  67.  
  68. // "at" returns the item at the specified index.
  69. //
  70. template <class T> const T& CmTOrderedArray<T>::at(int idx) const
  71. {
  72.   return _entries[idx];
  73. }
  74.  
  75.  
  76. // "[]" returns the item at the specified index.
  77. //
  78. template <class T> const T& CmTOrderedArray<T>::operator[](int idx) const
  79. {
  80.   return at(idx);
  81. }
  82.  
  83.  
  84. // "add" appends the specified item to this array.
  85. //
  86. template <class T> Bool CmTOrderedArray<T>::add(const T& rObj)
  87. {
  88.   if (_total >= _size)
  89.     if (_delta == 0 || !resize(_size+_delta))
  90.       return FALSE;
  91.  
  92.   int idx = shouldGo(rObj);
  93.   if (idx == -1) return FALSE;
  94.  
  95.   if (idx != _total)
  96.   {
  97.     for (int ii = _total; ii > idx; ii--)
  98.       _entries[ii] = _entries[ii-1];
  99.   }
  100.  
  101.   _entries[idx] = rObj;
  102.   _total++;
  103.   return TRUE;
  104. }
  105.  
  106.  
  107. // "remove" removes the first occurrence of an item equal to the specified
  108. // item in the array.
  109. //
  110. template <class T> Bool CmTOrderedArray<T>::remove(const T& rObj)
  111. {
  112.   if (_total == 0) return FALSE;
  113.   int  ii    = 0;
  114.   Bool found = FALSE;
  115.   while (ii < _total && !found)
  116.     if (_entries[ii++] == rObj) found = TRUE;
  117.   return (found) ? removeAt(ii-1) : FALSE;
  118. }
  119.  
  120.  
  121. // "removeAt" removes the item at the specified index.
  122. //
  123. template <class T> Bool CmTOrderedArray<T>::removeAt(int idx)
  124. {
  125.   if (idx < 0 || idx >= _total) return FALSE;
  126.  
  127.   for (int ii = idx; ii < _total-1; ii++)
  128.     _entries[ii] = _entries[ii+1];
  129.   _total--;
  130.   return TRUE;
  131. }
  132.  
  133.  
  134. // "index" returns the index of the first occurrence of an item equal
  135. // to the specified item.
  136. //
  137. template <class T> int CmTOrderedArray<T>::index(const T& rObj) const
  138. {
  139.   int  ii  = 0;
  140.   int  idx = -1;
  141.   while (ii < _total && idx == -1)
  142.     if (_entries[ii++] == rObj) idx = ii-1;
  143.   return idx;
  144. }
  145.  
  146.  
  147. // "shouldGo" reports the index where the specified object would be
  148. // inserted if it were added to the array.
  149. //
  150. template <class T> int CmTOrderedArray<T>::shouldGo(const T& rObj) const
  151. {
  152.   if (_total == _size) return -1;
  153.  
  154.   if (_total == 0) return 0;
  155.   if (rObj >= _entries[_total-1]) return _total;
  156.  
  157.   int idx = -1;
  158.   int ii  = 0;
  159.   while (ii < _total && idx == -1)
  160.   {
  161.     if (rObj < _entries[ii]) idx = ii;
  162.     else                     ii++;
  163.   }
  164.   return idx;
  165. }
  166.  
  167.  
  168. // "lookup" returns the first occurrence of the item equal to the
  169. // specified item in the array.
  170. //
  171. template <class T> const T& CmTOrderedArray<T>::lookup(const T& rObj) const
  172. {
  173.   int idx = index(rObj);
  174.   return (idx > -1) ? _entries[idx] : _error;
  175. }
  176.  
  177.  
  178. // "contains" checks the array for an item equal to the input.
  179. //
  180. template <class T> Bool CmTOrderedArray<T>::contains(const T& rObj) const
  181. {
  182.   return (index(rObj) > -1) ? TRUE : FALSE;
  183. }
  184.  
  185.  
  186. // "occurrences" counts the number of occurrences of items equal to the
  187. // specified item.
  188. //
  189. template <class T> unsigned CmTOrderedArray<T>::occurrences(const T& rObj) const
  190. {
  191.   int      ii  = 0;
  192.   unsigned num = 0;
  193.   while (ii < _total)
  194.     if (_entries[ii++] == rObj) num++;
  195.   return num;
  196. }
  197.  
  198.  
  199. // "resize" resizes the storage allocated for this array.
  200. //
  201. template <class T> Bool CmTOrderedArray<T>::resize(unsigned newSize)
  202. {
  203.   if (newSize == 0)
  204.   {
  205.     delete[] _entries;
  206.     _entries = NULL;
  207.     _size    = 0;
  208.     _total   = 0;
  209.     return TRUE;
  210.   }
  211.  
  212.   T *newEntries = new T[newSize];
  213.   if (!newEntries) return FALSE;
  214.  
  215.   if (newSize < _total) _total = newSize;
  216.  
  217.   for (int ii = 0; ii < _total; ii++)
  218.     newEntries[ii] = _entries[ii];
  219.  
  220.   delete[] _entries;
  221.   _entries = newEntries;
  222.   _size    = newSize;
  223.   return TRUE;
  224. }
  225.  
  226.  
  227. // "isEmpty" returns whether or not this array has any items in it.
  228. //
  229. template <class T> Bool CmTOrderedArray<T>::isEmpty() const
  230. {
  231.   return (_total == 0);
  232. }
  233.  
  234.  
  235. // "newIterator" creates and returns a new array iterator.
  236. //
  237. template <class T> CmTIterator<T>* CmTOrderedArray<T>::newIterator() const
  238. {
  239.   return new CmTOrderedArrayIterator<T>(*this);
  240. }
  241.  
  242.  
  243. // "copy" copies the items from the specified array into this array.
  244. //
  245. template <class T> void CmTOrderedArray<T>::copy(const CmTOrderedArray<T>& A)
  246. {
  247.   _size  = A._size;
  248.   _total = A._total;
  249.   _delta = A._delta;
  250.  
  251.   delete[] _entries;
  252.   _entries = (_size > 0) ? new T[_size] : NULL;
  253.   if (!_entries)
  254.   {
  255.     _total = 0;
  256.     _size  = 0;
  257.   }
  258.   else
  259.   {
  260.     for (int ii = 0; ii < _total; ii++)
  261.       _entries[ii] = A._entries[ii];
  262.   }
  263. }
  264.  
  265.  
  266. // "done" returns whether or not this iterator can advance any further.
  267. //
  268. template <class T> Bool CmTOrderedArrayIterator<T>::done() const
  269. {
  270.   return (_index >= _array._total || _index < 0);
  271. }
  272.  
  273.  
  274. // "next" returns the current item in the array and advances the
  275. // iterator to the next item.
  276. //
  277. template <class T> const T& CmTOrderedArrayIterator<T>::next()
  278. {
  279.   if (_index < _array._total) return _array._entries[_index++];
  280.   else                        return _array._error;
  281. }
  282.  
  283.  
  284. // "previous" returns the current item in the array and decrements the
  285. // iterator to the previous item.
  286. //
  287. template <class T> const T& CmTOrderedArrayIterator<T>::previous()
  288. {
  289.   if (_index >= 0) return _array._entries[_index--];
  290.   else             return _array._error;
  291. }
  292.  
  293.  
  294. // "current" returns the current array item.
  295. //
  296. template <class T> const T& CmTOrderedArrayIterator<T>::current() const
  297. {
  298.   if (_index < _array._total) return _array._entries[_index];
  299.   else                        return _array._error;
  300. }
  301.  
  302.  
  303. // "first" moves the iterator to the first item.
  304. //
  305. template <class T> void CmTOrderedArrayIterator<T>::first()
  306. {
  307.   _index = 0;
  308. }
  309.  
  310.  
  311. // "last" moves the iterator to the last item.
  312. //
  313. template <class T> void CmTOrderedArrayIterator<T>::last()
  314. {
  315.   _index = _array._total - 1;
  316. }
  317.